`timescale 1ns / 1ps
/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-29     Lyons        first version
 */

module pa_core_pcgen (
    clk_i,                      // system clock
    rst_n_i,                    // system reset

    reset_flag_i,               // need reset

    hold_flag_i,                // need hold

    jump_flag_i,                // need jump
    jump_addr_i,                // jump-to pc value

    pc_o                        // next pc value
    );

`include "../pa_chip_param.v"

input                           clk_i;
input                           rst_n_i;

input                           reset_flag_i;

input                           hold_flag_i;

input                           jump_flag_i;
input  [`DATA_BUS_WIDTH-1:0]    jump_addr_i;

output [`DATA_BUS_WIDTH-1:0]    pc_o;

wire                            clk_i;
wire                            rst_n_i;

wire                            reset_flag_i;

wire                            hold_flag_i;

wire                            jump_flag_i;
wire [`DATA_BUS_WIDTH-1:0]      jump_addr_i;

wire [`DATA_BUS_WIDTH-1:0]      pc_o;


reg  [`DATA_BUS_WIDTH-1:0]      _pc;

always @ (posedge clk_i) begin
// hardware power-on reset
    if (~rst_n_i) begin
        _pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
    end
// software reset
    else if (reset_flag_i) begin
        _pc[`DATA_BUS_WIDTH-1:0] <= `RESET_PC_ADDR;
    end
// jump instruction
    else if (jump_flag_i) begin
        _pc[`DATA_BUS_WIDTH-1:0] <= jump_addr_i[`DATA_BUS_WIDTH-1:0];
    end
// cpu stall & hold
    else if (hold_flag_i) begin
        _pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0];
    end
// only support 32-bits instruction
    else begin
        _pc[`DATA_BUS_WIDTH-1:0] <= _pc[`DATA_BUS_WIDTH-1:0] + 32'h4;
    end
end

assign pc_o[`DATA_BUS_WIDTH-1:0] = _pc[`DATA_BUS_WIDTH-1:0];

endmodule